package com.vcc.boss.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaCheckSafe;
import cn.idev.excel.ExcelWriter;
import cn.idev.excel.write.metadata.WriteSheet;
import com.mybatisflex.core.paginate.Page;
import com.vcc.boss.core.component.OssComponent;
import com.vcc.core.annotations.RestPack;
import com.vcc.core.derive.admin.DeriveWithdraw;
import com.vcc.core.exception.ProgramException;
import com.vcc.core.util.ExportUtil;
import com.vcc.core.util.RegexUtil;
import com.vcc.data.entity.*;
import com.vcc.service.boss.request.withdraw.AuditOrderDto;
import com.vcc.service.boss.response.withdraw.WithdrawVo;
import com.vcc.service.service.BossUserService;
import com.vcc.service.service.UserService;
import com.vcc.service.service.WalletService;
import com.vcc.service.service.WithdrawService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.RoundingMode;
import java.util.List;

@Log4j2
@RestController
@RequestMapping("withdraw")
public class WithdrawController {


    @Autowired
    private WithdrawService withdrawService;
    @Autowired
    private WalletService walletService;
    @Autowired
    private UserService userService;
    @Autowired
    private OssComponent ossComponent;
    @Autowired
    private BossUserService bossUserService;


    @RestPack
    @SaCheckPermission(value = "wallet:withdraw:list:view")
    @SaCheckLogin
    @GetMapping("paging")
    public Page<WithdrawVo> paging(
            Integer pageNumber,
            Integer pageSize,
            Long targetUserId,
            String type,
            Integer status,
            String startDate,
            String endDate,
            String remark,
            Long dealerId
    ) {
        Page<Withdraw> paging = withdrawService.paging(
                Page.of(
                        pageNumber == null ? 1 : pageNumber,
                        pageSize == null ? 20 : pageSize
                ),
                targetUserId,
                type,
                status,
                startDate,
                endDate,
                remark,
                dealerId);
        if (paging.getRecords().isEmpty()) {
            return Page.of(paging.getPageNumber(), paging.getPageSize());
        }
        return paging.map(it -> {

            return new WithdrawVo(it);
        });
    }

    @GetMapping("derive")
    @SaCheckPermission(value = "wallet:withdraw:list:derive")
    public void derive(
            Long targetUserId,
            String type,
            Integer status,
            String startDate,
            String endDate,
            String remark,
            Long dealerId,
            HttpServletResponse response
    ) {
        if (RegexUtil.checkStringIsNull(startDate)) {
            throw new ProgramException("请选择开始时间");
        }
        if (RegexUtil.checkStringIsNull(endDate)) {
            throw new ProgramException("请选择结束时间");
        }
        Long pages = 1L;
        Page<Withdraw> paging;
        String fileName = System.currentTimeMillis() + "提现订单.xlsx";
        ExcelWriter excelWriter;
        try {
            ExportUtil.setExcelResponseHeaders(response, fileName);
            excelWriter = ExportUtil.createExcelWriter(response.getOutputStream(), DeriveWithdraw.class);
        } catch (Exception e) {
            log.error("导出提现订单数据失败", e);
            throw new ProgramException("导出提现订单数据失败");
        }
        WriteSheet writeSheet = ExportUtil.createWriteSheet("提现订单", DeriveWithdraw.class);
        try {
            do {
                paging = withdrawService.paging(
                        Page.of(
                                pages++,
                                500
                        ),
                        targetUserId,
                        type,
                        status,
                        startDate,
                        endDate,
                        remark,
                        dealerId);
                List<DeriveWithdraw> list = paging.getRecords().stream().map(it -> DeriveWithdraw.builder()
                        .id(it.getId())
                        .orderId(it.getOrderId())
                        .requestDate(it.getRequestDate())
                        .account(it.getAccount())
                        .amount(it.getAmount())
                        .address(it.getAddress())
                        .remittanceAmount(it.getAmount().subtract(it.getFree()).setScale(2, RoundingMode.HALF_DOWN))
                        .currency(it.getWithdrawCurrency())
                        .hash(it.getOrderHash())
                        .network(it.getType())
                        .remark(it.getRemark())
                        .status(it.getStatus())
                        .auditDate(it.getAuditDate())
                        .auditAccount(it.getAuditAccount())
                        .dealerAccount(it.getDealerAccount())
                        .build()).toList();
                ExportUtil.writeData(excelWriter, writeSheet, list);
                list = null;
            } while (!(pages).equals(paging.getTotalPage() + 1));
        } catch (Exception e) {
            log.error("导出失败", e);
            throw new ProgramException("导出失败");
        }
        ExportUtil.closeExcelWriter(excelWriter);

    }

    //
    @RestPack
    @SaCheckPermission(value = "wallet:withdraw:list:audit")
    @PostMapping("audit")
    @SaCheckSafe("CLIENT_ORDER_AUDIT")
    public Boolean audit(
            @RequestBody @Validated AuditOrderDto auditOrderDto
    ) {
        return withdrawService.audit(auditOrderDto);
    }
}
